﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YJKGeometryFuncs;

namespace YJKArchUtils.StructurePoleSuit
{
	public class ColumnLoopSearcher : BaseColumnLoopSearcher
	{
		public ColumnLoopSearcher(ExternalCommandData commandData, List<ColumnProfilePart> partList, bool isSearchEdgeLoops, XYZ selecetBoxMin = null, XYZ selecetBoxMax = null, Dictionary<XYZ, bool> pointTag = null, bool bIsEdgeComponentEditing = false) : base(commandData, isSearchEdgeLoops, selecetBoxMin, selecetBoxMax, pointTag)
		{
			this.m_Revit = commandData;
			this.m_IsSearchEdgeLoops = isSearchEdgeLoops;
			List<Structure2DPole> list = new List<Structure2DPole>();
			foreach (ColumnProfilePart item in partList)
			{
				list.Add(item);
			}
			base.InitData(list, ref this.m_Nodes);
			if (bIsEdgeComponentEditing)
			{
				this.FilterNodesBySelectBoxEdgeComponent(ref this.m_Nodes);
				return;
			}
			this.FilterNodesBySelectBox(ref this.m_Nodes);
		}

		public void GetEdgeLoopsByEdgeList(ref List<List<Curve>> profileEdgeLoop, ref List<KeyValuePair<string, Curve>> showCenterCurve, ref List<KeyValuePair<string, Curve>> hideCenterCurve)
		{
			List<Structure2DNode> nodes = this.FindCheckedNodes();
			base.TrimAllNode(ref nodes);
			this.ResetLength(ref nodes);
			base.TrimAllNode(ref nodes);
			this.GetEndCenterCurves(nodes, ref showCenterCurve, ref hideCenterCurve);
			base.GetProfileCurves(nodes, ref profileEdgeLoop);
		}

		public List<ColumnProfilePart> GetCurrentEndPartList()
		{
			return this.GetCurrentEndPartList(this.m_Nodes);
		}

		public double GetLength(ElementId componentId)
		{
			foreach (Structure2DNode structure2DNode in this.m_Nodes)
			{
				XYZ position = structure2DNode.Position;
				foreach (Structure2DPole structure2DPole in structure2DNode.PoleList)
				{
					if (structure2DPole.ComponentId.IntegerValue == componentId.IntegerValue)
					{
						return (structure2DPole as ColumnProfilePart).ExtendLength;
					}
				}
			}
			return 0.0;
		}

		public void ResetLength(ElementId componentId, double newLength)
		{
			foreach (Structure2DNode structure2DNode in this.m_Nodes)
			{
				XYZ position = structure2DNode.Position;
				foreach (Structure2DPole structure2DPole in structure2DNode.PoleList)
				{
					if (structure2DPole.ComponentId.IntegerValue == componentId.IntegerValue)
					{
						(structure2DPole as ColumnProfilePart).ExtendLength = newLength;
					}
				}
			}
		}

		public void SetChecked(ElementId componentId, bool isChecked)
		{
			foreach (Structure2DNode structure2DNode in this.m_Nodes)
			{
				XYZ position = structure2DNode.Position;
				foreach (Structure2DPole structure2DPole in structure2DNode.PoleList)
				{
					if (structure2DPole.ComponentId.IntegerValue == componentId.IntegerValue)
					{
						(structure2DPole as ColumnProfilePart).Checked = isChecked;
					}
				}
			}
		}

		private List<Structure2DNode> FindCheckedNodes()
		{
			List<Structure2DPole> list = new List<Structure2DPole>();
			foreach (Structure2DNode structure2DNode in this.m_Nodes)
			{
				foreach (Structure2DPole structure2DPole in structure2DNode.PoleList)
				{
					ColumnProfilePart part = structure2DPole as ColumnProfilePart;
					ColumnProfilePart item = new ColumnProfilePart(part);
					if (list.FindIndex((Structure2DPole s) => s.SameAs(part)) <= -1)
					{
						list.Add(item);
					}
				}
			}
			List<Structure2DNode> list2 = new List<Structure2DNode>();
			base.InitData(list, ref list2);
			for (int i = 0; i < list2.Count; i++)
			{
				Structure2DNode structure2DNode2 = list2[i];
				XYZ position = structure2DNode2.Position;
				Structure2DNode structure2DNode3 = base.FindNodeByPos(this.m_Nodes, position);
				if (structure2DNode3 == null)
				{
					structure2DNode2.Tag = "false";
				}
				else
				{
					structure2DNode2.Tag = structure2DNode3.Tag;
				}
				for (int j = 0; j < structure2DNode2.PoleList.Count; j++)
				{
					Structure2DPole structure2DPole2 = structure2DNode2.PoleList[j];
					if (!(structure2DPole2 as ColumnProfilePart).Checked)
					{
						Structure2DNode structure2DNode4 = base.FindNodeByPos(list2, structure2DPole2.CurOutNodePosition(position));
						if (structure2DNode4 != null)
						{
							List<int> indexList = structure2DNode4.FindLinkPoleWithOtherNode(position);
							structure2DNode4.RemoveSortEdges(indexList);
							structure2DNode2.RemoveEdge(j);
							j--;
						}
					}
				}
			}
			for (int i = 0; i < list2.Count; i++)
			{
				if (list2[i].PoleList.Count == 0)
				{
					list2.RemoveAt(i);
					i--;
				}
			}
			return list2;
		}

		private void FilterNodesBySelectBoxEdgeComponent(ref List<Structure2DNode> nodes)
		{
			foreach (Structure2DNode structure2DNode in nodes)
			{
				structure2DNode.Tag = base.IsPointMove(structure2DNode.Position).ToString();
			}
			for (int i = 0; i < nodes.Count; i++)
			{
				Structure2DNode structure2DNode2 = nodes[i];
				XYZ position = structure2DNode2.Position;
				bool flag = this.NodeInBox(structure2DNode2);
				for (int j = 0; j < structure2DNode2.PoleList.Count; j++)
				{
					Structure2DPole structure2DPole = structure2DNode2.PoleList[j];
					Structure2DNode structure2DNode3 = base.FindNodeByPos(nodes, structure2DPole.CurOutNodePosition(position));
					if (structure2DNode3 == null)
					{
						structure2DNode2.RemoveEdge(j);
						j--;
					}
					else if ((this.NodeInBox(structure2DNode3) || flag) && (!this.NodeInBox(structure2DNode3) || !flag) && flag)
					{
						ColumnProfilePart columnProfilePart = structure2DPole as ColumnProfilePart;
						List<int> indexList = structure2DNode3.FindLinkPoleWithOtherNode(position);
						structure2DNode3.RemoveSortEdges(indexList);
						columnProfilePart.ResetEndWithCurve(position, false);
						List<Structure2DPole> list = new List<Structure2DPole>();
						list.Add(columnProfilePart);
						Structure2DNode item = new Structure2DNode(columnProfilePart.CurOutNodePosition(position), list);
						nodes.Add(item);
					}
				}
			}
			for (int i = 0; i < nodes.Count; i++)
			{
				if (nodes[i].PoleList.Count == 0)
				{
					nodes.RemoveAt(i);
					i--;
				}
			}
		}

		private void FilterNodesBySelectBox(ref List<Structure2DNode> nodes)
		{
			foreach (Structure2DNode structure2DNode in nodes)
			{
				structure2DNode.Tag = base.IsPointMove(structure2DNode.Position).ToString();
			}
			for (int i = 0; i < nodes.Count; i++)
			{
				Structure2DNode structure2DNode2 = nodes[i];
				XYZ position = structure2DNode2.Position;
				bool flag = this.NodeInBox(structure2DNode2);
				for (int j = 0; j < structure2DNode2.PoleList.Count; j++)
				{
					Structure2DPole structure2DPole = structure2DNode2.PoleList[j];
					Structure2DNode structure2DNode3 = base.FindNodeByPos(nodes, structure2DPole.CurOutNodePosition(position));
					if (structure2DNode3 == null)
					{
						structure2DNode2.RemoveEdge(j);
						j--;
					}
					else if (!this.NodeInBox(structure2DNode3) && !flag)
					{
						structure2DNode2.RemoveEdge(j);
						j--;
					}
					else if ((!this.NodeInBox(structure2DNode3) || !flag) && flag)
					{
						ColumnProfilePart columnProfilePart = structure2DPole as ColumnProfilePart;
						List<int> indexList = structure2DNode3.FindLinkPoleWithOtherNode(position);
						structure2DNode3.RemoveSortEdges(indexList);
						columnProfilePart.ResetEndWithCurve(position, false);
						List<Structure2DPole> list = new List<Structure2DPole>();
						list.Add(columnProfilePart);
						Structure2DNode item = new Structure2DNode(columnProfilePart.CurOutNodePosition(position), list);
						nodes.Add(item);
					}
				}
			}
			for (int i = 0; i < nodes.Count; i++)
			{
				if (nodes[i].PoleList.Count == 0)
				{
					nodes.RemoveAt(i);
					i--;
				}
			}
		}

		public List<ColumnProfilePart> GetCurrentAllPartList()
		{
			return base.GetCurrentAllPartList(this.m_Nodes);
		}

		private List<ColumnProfilePart> GetCurrentEndPartList(List<Structure2DNode> nodes)
		{
			List<ColumnProfilePart> list = new List<ColumnProfilePart>();
			if (nodes.Count == 2 && nodes[0].PoleList.Count == 1 && nodes[1].PoleList.Count == 1)
			{
				for (int i = 0; i < nodes.Count; i++)
				{
					Structure2DNode structure2DNode = nodes[i];
					XYZ position = structure2DNode.Position;
					if ((!this.NodeInBox(nodes[0]) || !this.NodeInBox(nodes[1])) && this.NodeInBox(structure2DNode))
					{
						Structure2DPole structure2DPole = structure2DNode.PoleList[0];
						ColumnProfilePart part = structure2DPole as ColumnProfilePart;
						if (list.FindIndex((ColumnProfilePart s) => s.SameAs(part)) <= -1)
						{
							list.Add(part);
						}
					}
				}
				return list;
			}
			foreach (Structure2DNode structure2DNode2 in nodes)
			{
				XYZ position2 = structure2DNode2.Position;
				foreach (Structure2DPole structure2DPole2 in structure2DNode2.PoleList)
				{
					ColumnProfilePart part = structure2DPole2 as ColumnProfilePart;
					Structure2DNode structure2DNode3 = base.FindNodeByPos(nodes, structure2DPole2.CurOutNodePosition(position2));
					if (structure2DNode3 != null && (structure2DNode2.PoleList.Count <= 1 || structure2DNode3.PoleList.Count <= 1) && list.FindIndex((ColumnProfilePart s) => s.SameAs(part)) <= -1 && (!this.NodeInBox(structure2DNode2) || !this.NodeInBox(structure2DNode3)))
					{
						list.Add(part);
					}
				}
			}
			return list;
		}

		private void ResetLength(ref List<Structure2DNode> theNodes)
		{
			if (theNodes.Count == 2 && theNodes[0].PoleList.Count == 1 && theNodes[1].PoleList.Count == 1)
			{
				for (int i = 0; i < theNodes.Count; i++)
				{
					Structure2DNode structure2DNode = theNodes[i];
					Structure2DNode structure2DNode2;
					if (i == 0)
					{
						structure2DNode2 = theNodes[1];
					}
					else
					{
						structure2DNode2 = theNodes[0];
					}
					ColumnProfilePart columnProfilePart = structure2DNode.PoleList[0] as ColumnProfilePart;
					XYZ position = structure2DNode.Position;
					if ((!this.NodeInBox(structure2DNode2) || !this.NodeInBox(structure2DNode)) && this.NodeInBox(structure2DNode))
					{
						columnProfilePart.ResetEndWithCurve(position, false);
						structure2DNode2.Position = columnProfilePart.CurOutNodePosition(position);
					}
				}
				return;
			}
			foreach (Structure2DNode structure2DNode3 in theNodes)
			{
				XYZ position2 = structure2DNode3.Position;
				foreach (Structure2DPole structure2DPole in structure2DNode3.PoleList)
				{
					Structure2DNode structure2DNode4 = base.FindNodeByPos(theNodes, structure2DPole.CurOutNodePosition(position2));
					if (structure2DNode4 != null && (structure2DNode3.PoleList.Count <= 1 || structure2DNode4.PoleList.Count <= 1))
					{
						bool flag = this.NodeInBox(structure2DNode3);
						bool flag2 = this.NodeInBox(structure2DNode4);
						if ((!flag || !flag2) && flag)
						{
							ColumnProfilePart columnProfilePart2 = structure2DPole as ColumnProfilePart;
							columnProfilePart2.ResetEndWithCurve(position2, false);
							structure2DNode4.Position = columnProfilePart2.CurOutNodePosition(position2);
						}
					}
				}
			}
		}

		private bool NodeInBox(Structure2DNode node)
		{
			bool result = false;
			try
			{
				result = Convert.ToBoolean(node.Tag);
			}
			catch (Exception)
			{
				return result;
			}
			return result;
		}

		private void GetEndCenterCurves(List<Structure2DNode> nodes, ref List<KeyValuePair<string, Curve>> showCenterCurves, ref List<KeyValuePair<string, Curve>> hideCenterCurve)
		{
			List<ColumnProfilePart> currentAllPartList = base.GetCurrentAllPartList(nodes);
			List<ColumnProfilePart> currentEndPartList = this.GetCurrentEndPartList(nodes);
			List<ColumnProfilePart> list = new List<ColumnProfilePart>();
			using (List<ColumnProfilePart>.Enumerator enumerator = currentAllPartList.GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					ColumnProfilePart pole = enumerator.Current;
					if (currentEndPartList.FindIndex((ColumnProfilePart s) => s.Number == pole.Number) < 0)
					{
						list.Add(pole);
					}
				}
			}
			foreach (ColumnProfilePart columnProfilePart in currentEndPartList)
			{
				bool flag = true;
				if (columnProfilePart.IsValidSideLineOfPositive() != Structure2DPole._tagSideLineValidType._Valide || columnProfilePart.IsValidSideLineOfNegative() != Structure2DPole._tagSideLineValidType._Valide)
				{
					flag = false;
				}
				if (flag)
				{
					KeyValuePair<string, Curve> number2ndCenterCurve = this.GetNumber2ndCenterCurve(columnProfilePart);
					showCenterCurves.Add(number2ndCenterCurve);
				}
				else
				{
					KeyValuePair<string, Curve> number2ndCenterCurveByHidePole = this.GetNumber2ndCenterCurveByHidePole(columnProfilePart);
					hideCenterCurve.Add(number2ndCenterCurveByHidePole);
				}
			}
			foreach (ColumnProfilePart pole2 in list)
			{
				KeyValuePair<string, Curve> number2ndCenterCurveByHidePole2 = this.GetNumber2ndCenterCurveByHidePole(pole2);
				hideCenterCurve.Add(number2ndCenterCurveByHidePole2);
			}
		}

		private KeyValuePair<string, Curve> GetNumber2ndCenterCurveByHidePole(ColumnProfilePart pole)
		{
			double bulge = pole.Bulge;
			XYZ startPoint = pole.StartPoint;
			XYZ endPoint = pole.EndPoint;
			return new KeyValuePair<string, Curve>(pole.Number.ToString(), base.GetCurve(startPoint, endPoint, bulge));
		}

		private KeyValuePair<string, Curve> GetNumber2ndCenterCurve(ColumnProfilePart pole)
		{
			double bugle = pole.Bulge;
			XYZ xyz = pole.StartPoint;
			XYZ xyz2 = pole.EndPoint;
			double val = pole.Length();
			double num = pole.PositiveSideLineLength();
			double val2 = pole.NegativeSideLineLength();
			if (!Geometry.IsEqual(val, num) || !Geometry.IsEqual(val, val2))
			{
				if (Geometry.LessThan(num, val2))
				{
					xyz = pole.CalculateFootPointOnAxis(pole.PositiveStartPoint);
					xyz2 = pole.CalculateFootPointOnAxis(pole.PositiveEndPoint);
				}
				else
				{
					xyz = pole.CalculateFootPointOnAxis(pole.NegativeStartPoint);
					xyz2 = pole.CalculateFootPointOnAxis(pole.NegativeEndPoint);
				}
				if (pole.IsArcPole)
				{
					bugle = Geometry.GetBulge(xyz, xyz2, pole.Center, Geometry.Greaterthan_Or_Equal(pole.Bulge, 0.0));
				}
				else
				{
					bugle = 0.0;
				}
			}
			return new KeyValuePair<string, Curve>(pole.Number.ToString(), base.GetCurve(xyz, xyz2, bugle));
		}

		private List<Structure2DNode> m_Nodes = new List<Structure2DNode>();
	}
}
